<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- SEO 优化 -->
    <title>净利润断层 - 价值投资盯盘系统</title>
    <meta name="description" content="净利润断层分析页面，提供股票净利润断层数据监控、分析功能，助您把握投资机会。">
    <meta name="keywords" content="净利润断层,股票分析,价值投资,财务分析,投资机会">
    <meta name="author" content="ZYJ">
    <meta name="robots" content="index, follow">
    <!-- Open Graph 标签 -->
    <meta property="og:title" content="净利润断层 - 价值投资盯盘系统">
    <meta property="og:description" content="提供股票净利润断层数据监控、分析功能，助您把握投资机会。">
    <meta property="og:type" content="website">
    <!-- 其他元标签 -->
    <meta name="application-name" content="价值投资盯盘系统">
    <meta name="theme-color" content="#1e3c72">
    <link rel="canonical" href="https://your-domain.com/net-profit-gap" />
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
    <style>
        body {
            background-color: #f8f9fa;
            margin-bottom: 60px;
        }
        .navbar {
            background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
            height: 50px;
            padding: 0;
        }
        .navbar-brand {
            color: white;
            font-size: 16px;
            text-decoration: none;
            margin-right: 50px;
        }
        .navbar-nav {
            display: flex;
            list-style: none;
            margin: 0;
            padding: 0;
        }
        .nav-item {
            margin-right: 30px;
        }
        .nav-link {
            color: white !important;
            text-decoration: none;
            font-size: 14px;
            line-height: 50px;
            padding: 0;
        }
        .nav-link.active {
            font-weight: bold;
        }
        .iconfont {
            font-size: 14px;
            margin-right: 4px;
        }
        .card {
            border: none;
            border-radius: 10px;
            box-shadow: 0 0 20px rgba(0,0,0,0.05);
            margin-bottom: 20px;
        }
        .card-header {
            background: white;
            border-bottom: 1px solid rgba(0,0,0,0.05);
            padding: 1rem 1.5rem;
            font-weight: 600;
            color: #1e3c72;
        }
        .table {
            margin-bottom: 0;
        }
        .table th {
            font-weight: 600;
            color: #495057;
            border-bottom: 2px solid #dee2e6;
            white-space: nowrap;
        }
        .table td {
            vertical-align: middle;
            white-space: nowrap;
        }
        /* 为"变动原因"列添加特殊样式 */
        .reason-column {
            width: 200px;
            max-width: 200px;
        }
        .table td:nth-child(8),
        .table .reason-column {
            white-space: normal;
            word-wrap: break-word;
            max-width: 200px;
            width: 200px;
            word-break: break-word;
        }
        .alert-value {
            background-color: rgba(255, 193, 7, 0.1);
        }
        .alert-name {
            color: #dc3545;
            font-weight: bold;
        }
        .btn-primary {
            background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
            border: none;
            padding: 0.5rem 1.5rem;
        }
        .btn-primary:hover {
            background: linear-gradient(135deg, #2a5298 0%, #1e3c72 100%);
        }
        .btn-outline-primary {
            color: #1e3c72;
            border-color: #1e3c72;
        }
        .btn-outline-primary:hover {
            background-color: #1e3c72;
            border-color: #1e3c72;
        }
        .btn-danger {
            background-color: #dc3545;
            border: none;
        }
        .form-control:focus {
            border-color: #1e3c72;
            box-shadow: 0 0 0 0.2rem rgba(30, 60, 114, 0.25);
        }
        .positive-value {
            color: #dc3545;  /* 红色 */
        }
        .negative-value {
            color: #28a745;  /* 绿色 */
        }
        .table-container {
            overflow-x: auto;
            border-radius: 10px;
            position: relative;
        }
        .table {
            margin-bottom: 0;
            position: relative;
        }
        .table thead {
            position: sticky;
            top: 0;
            z-index: 1;
            background: white;
        }
        .table thead th {
            position: sticky;
            top: 0;
            background: white;
            box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.1);
        }
        .table tfoot {
            position: sticky;
            bottom: 0;
            background: #f8f9fa;
            box-shadow: 0 -2px 2px -1px rgba(0, 0, 0, 0.1);
        }
        .table tbody tr:last-child td {
            border-bottom: none;
        }
        .card-body.p-0 {
            overflow: hidden;
        }
        .refresh-icon {
            margin-right: 5px;
        }
        .sortable {
            cursor: pointer;
            user-select: none;
        }
        .sortable:hover {
            background-color: rgba(0,0,0,0.05);
        }
        .sortable.asc .bi-arrow-down-up::before {
            content: "\f12d"; /* bootstrap icon for up arrow */
        }
.sortable.desc .bi-arrow-down-up::before {
            content: "\f128"; /* bootstrap icon for down arrow */
        }
        .loading {
            opacity: 0.5;
        }
        .loading-spinner {
            display: inline-block;
            width: 1rem;
            height: 1rem;
            border: 2px solid #f3f3f3;
            border-top: 2px solid #3498db;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .data-loading {
            color: #666;
            font-size: 0.8rem;
        }
        .index-container {
            background: #f8f9fa;
            border-top: 1px solid #dee2e6;
        }
        .index-card {
            background: white;
            border-radius: 8px;
            padding: 10px;
            margin: 5px;
            min-width: 200px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
        }
        .index-name {
            font-size: 14px;
            font-weight: 600;
            margin-bottom: 5px;
        }
        .index-price {
            font-size: 16px;
            font-weight: bold;
        }
        .index-change {
            font-size: 12px;
            padding: 2px 6px;
            border-radius: 4px;
        }
        .index-chart {
            width: 160px;
            height: 60px;
            margin-top: 5px;
        }
        .index-panel {
            background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            border-top: 1px solid rgba(255,255,255,0.1);
        }
        .index-card {
            background: rgba(255,255,255,0.1);
            border-radius: 8px;
            padding: 12px;
            margin: 5px;
            min-width: 220px;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255,255,255,0.2);
        }
        .index-name {
            font-size: 14px;
            font-weight: 600;
            margin-bottom: 5px;
            color: rgba(255,255,255,0.9);
        }
        .index-price {
            font-size: 18px;
            font-weight: bold;
            color: white;
        }
        .index-change {
            font-size: 13px;
            padding: 2px 8px;
            border-radius: 4px;
            background: rgba(0,0,0,0.2);
        }
        .index-chart {
            width: 200px;
            height: 60px;
            margin-top: 8px;
        }
        .navbar-toggler {
            color: white;
            border-color: rgba(255,255,255,0.3);
            padding: 0.5rem 1rem;
font-size: 0.9rem;
        }
        .navbar-toggler:focus {
            box-shadow: none;
        }
        .navbar-nav {
            margin-left: 30px;
        }
        .nav-link {
            color: rgba(255,255,255,0.8) !important;
            padding: 0.5rem 1rem;
            transition: color 0.2s;
        }
        .nav-link:hover {
            color: white !important;
        }
        .nav-link.active {
            color: white !important;
            font-weight: 600;
        }
        /* 添加下拉菜单z-index修复 */
        .dropdown-menu {
            z-index: 1050; /* 确保下拉菜单在其他内容之上 */
        }
        
        .navbar-nav {
            z-index: 1040; /* 确保导航栏也有适当的层级 */
        }
        /* 添加弹窗相关样式 */
        .modal-body {
            padding: 1.5rem;
        }
        .modal-body .table td {
            padding: 0.75rem;
            vertical-align: top;
            word-break: break-word;
            white-space: normal;
line-height: 1.5;
        }
        .modal-body .table td:first-child {
            width: 140px;
            min-width: 140px;
            font-weight: 500;
            color: #495057;
            background-color: rgba(0,0,0,0.02);
        }
        .modal-body .table td:last-child {
            width: auto;
            overflow-wrap: break-word;
        }
        .modal-body .card {
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
            border: 1px solid rgba(0,0,0,0.1);
        }
        .modal-body .card-header {
            background-color: #f8f9fa;
            border-bottom: 1px solid rgba(0,0,0,0.1);
            padding: 0.75rem 1rem;
        }
        .modal-body .card-body {
            padding: 1rem;
        }
        .modal-body .table {
            margin-bottom: 0;
        }
        .modal-body .table tr:last-child {
            border-bottom: none;
        }
        .modal-body .table a {
            color: #1e3c72;
            text-decoration: none;
        }
        .modal-body .table a:hover {
            text-decoration: underline;
        }
        .modal-body h6.text-muted {
            font-size: 0.875rem;
            font-weight: 600;
            margin-bottom: 0.5rem;
        }
        .modal-body .alert {
            margin-bottom: 1rem;
            padding: 0.75rem;
        }
        .modal-body .alert-info {
            background-color: rgba(30,60,114,0.1);
            border: none;
            color: #1e3c72;
        }
        @media (max-width: 768px) {
            .modal-body .table td:first-child {
                width: 120px;
                min-width: 120px;
            }
        }
        /* 美化滚动条 */
        .modal-body::-webkit-scrollbar {
            width: 8px;
        }
        .modal-body::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 4px;
        }
        .modal-body::-webkit-scrollbar-thumb {
            background: #888;
            border-radius: 4px;
        }
        .modal-body::-webkit-scrollbar-thumb:hover {
            background: #555;
        }
        /* Footer 样式 */
        .footer {
            background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
            color: white;
            text-align: center;
            padding: 15px 0;
            width: 100%;
            font-size: 14px;
            margin: 0;
        }
        .footer a {
            color: white;
            text-decoration: none;
        }
        .footer a:hover {
            text-decoration: underline;
        }
        /* 修改容器样式 */
        .container {
            margin-bottom: 0;
            padding-bottom: 0;
        }
        .card:last-child {
            margin-bottom: 0;
        }
    </style>
</head>
<body>
    <nav class="navbar navbar-dark">
        <div class="container-fluid px-4">
            <span class="navbar-brand">
                <i class="bi bi-graph-up"></i>
                价值投资盯盘系统
            </span>
            
            <!-- 添加水平导航菜单，居左对齐，间距50px -->
            <div class="navbar-nav flex-row" style="margin-left: 50px;">
                <a class="nav-link" href="/" style="margin-right: 50px;">个股监控</a>
                <a class="nav-link active" href="/net-profit-gap">净利润断层</a>
            </div>
            
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#indexMarketPanel">
                <i class="bi bi-arrows-angle-expand"></i> 上传股票池
            </button>
        </div>
    </nav>
    
    <!-- 文件上传面板 -->
    <div class="collapse" id="indexMarketPanel">
        <div class="container-fluid index-panel">
            <div class="row justify-content-center">
                <div class="col-md-8">
                    <div class="card">
                        <div class="card-header">
                            <h5 class="mb-0">上传Excel文件</h5>
                        </div>
                        <div class="card-body">
                            <form id="uploadExcelForm">
                                <div class="mb-3">
                                    <label for="excelFile" class="form-label">选择Excel文件</label>
                                    <input type="file" class="form-control" id="excelFile" name="file" accept=".xlsx,.xls">
                                    <div class="form-text">支持.xlsx和.xls格式的文件</div>
                                </div>
                                <button type="submit" class="btn btn-primary">
                                    <i class="bi bi-upload"></i> 上传文件
                                </button>
                            </form>
                            <div id="uploadResult" class="mt-3" style="display: none;"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="container py-4">
        <!-- 净利润断层列表 -->
        <div class="card">
            <div class="card-header d-flex justify-content-between align-items-center">
                <span><i class="bi bi-table"></i> 净利润断层股票列表</span>
                <div>
                    <div class="input-group" style="width: auto;">
                        <input type="text" class="form-control form-control-sm" placeholder="搜索股票代码或名称" id="searchInput">
                        <button class="btn btn-outline-primary btn-sm" onclick="searchStocks()">
                            <i class="bi bi-search"></i> 搜索
                        </button>
                    </div>
                </div>
            </div>
            <div class="card-body p-0">
                <div class="table-container">
                    <table class="table table-hover">
                        <thead>
                            <tr>
                                <th class="sortable">代码 <i class="bi bi-arrow-down-up"></i></th>
                                <th class="sortable">名称 <i class="bi bi-arrow-down-up"></i></th>
                                <th class="sortable">公告日期 <i class="bi bi-arrow-down-up"></i></th>
                                <th class="sortable">断层日 <i class="bi bi-arrow-down-up"></i></th>
                                <th class="sortable">断层日涨幅 <i class="bi bi-arrow-down-up"></i></th>
                                <th class="sortable">预告净利润变动幅度 <i class="bi bi-arrow-down-up"></i></th>
                                <th class="sortable">预告摘要 <i class="bi bi-arrow-down-up"></i></th>
                                <th class="sortable reason-column">变动原因 <i class="bi bi-arrow-down-up"></i></th>
                                <th>操作</th>
                            </tr>
                        </thead>
                        <tbody id="profitGapTableBody">
                            <!-- 示例数据 -->
                        </tbody>
                        <tfoot>
                            <tr class="table-secondary">
                                <td colspan="11"><strong>统计(<span id="stockCount">0</span>只)</strong></td>
                            </tr>
                        </tfoot>
                    </table>
                </div>
            </div>
        </div>
    </div>

    <!-- 页脚 -->
    <footer class="footer mt-auto">
        <div class="container">
            <span>© 2023 价值投资盯盘系统 - 智能股票分析与监控平台</span>
        </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        
        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function() {
            // 初始化当日净利润断层股票
            getProfitGapStocks();

            refreshGaplist();
            
        });

        async function getProfitGapStocks() {
            try {
                const response = await fetch('/api/get_gap_stocks');
                if (!response.ok) throw new Error('获取股票数据失败');
            } catch (error) {
                console.error('获取净利润断层股票失败:', error);
                alert('获取数据失败：' + error.message);
                throw error; // 重新抛出错误，以便调用者可以处理
            }
        }

        // 渲染净利润断层列表
        function renderProfitGapList(data) {
            const profitGapTableBody = document.getElementById('profitGapTableBody');
            if (!profitGapTableBody) return;
            
            // 清空现有内容
            profitGapTableBody.innerHTML = '';
            
            // 检查数据是否为空
            if (!data || !Array.isArray(data) || data.length === 0) {
                const emptyRow = document.createElement('tr');
                emptyRow.innerHTML = '<td colspan="9" class="text-center text-muted py-4">暂无净利润断层股票</td>';
                profitGapTableBody.appendChild(emptyRow);
                document.getElementById('stockCount').textContent = '0';
                return;
            }
            
            // 渲染每一行
            data.forEach(item => {
                const row = document.createElement('tr');
                
                // 提取字段，设置默认值
                const ts_code = item.ts_code || '-';
                const stock_name = item.stock_name || '-';
                const announce_date = item.announce_date || '-';
                const gap_date = item.gap_date || '-';
                const gap_pct_change = item.gap_pct_change !== undefined ? item.gap_pct_change : '-';
                const forecast_change_min = item.forecast_change_min !== undefined ? item.forecast_change_min : '-';
                const forecast_change_max = item.forecast_change_max !== undefined ? item.forecast_change_max : '-';
                const summary = item.summary || '-';
                const reason = item.reason || '-';
                
                // 格式化预告净利润变动幅度
                let forecast_change_text = '-';
                if (forecast_change_min !== '-' && forecast_change_max !== '-') {
                    forecast_change_text = `${forecast_change_min}% ~ ${forecast_change_max}%`;
                } else if (forecast_change_min !== '-') {
                    forecast_change_text = `${forecast_change_min}%`;
                } else if (forecast_change_max !== '-') {
                    forecast_change_text = `${forecast_change_max}%`;
                }
                
                // 格式化断层日涨幅
                let gap_pct_change_text = gap_pct_change !== '-' ? `${gap_pct_change}%` : '-';
                
                // 处理变动原因列，只显示前15个字，鼠标悬停显示完整内容
                let reasonDisplay = reason;
                if (reason && reason.length > 15) {
                    reasonDisplay = `<span title="${reason}">${reason.substring(0, 15)}...</span>`;
                }
                
                row.innerHTML = `
                    <td>${ts_code}</td>
                    <td>${stock_name}</td>
                    <td>${announce_date}</td>
                    <td>${gap_date}</td>
                    <td>${gap_pct_change_text}</td>
                    <td>${forecast_change_text}</td>
                    <td>${summary}</td>
                    <td>${reasonDisplay}</td>
                    <td>
                        <button class="btn btn-sm btn-outline-primary me-1" onclick="showStockDetail('${ts_code}')">
                            <i class="bi bi-eye"></i> 查看
                        </button>
                    </td>
                `;
                
                profitGapTableBody.appendChild(row);
            });

            // 更新股票数量统计
            document.getElementById('stockCount').textContent = data.length;
        }

        // 刷新净利润断层列表
        async function refreshGaplist() {
            try {
                const response = await fetch('/api/gap_watchlist');
                console.log('获取净利润断层列表响应:', response);

                if (!response.ok) throw new Error('获取净利润断层列表失败');
                
                const rawData = await response.json();

                // 解析后端返回的数据格式
                const data = rawData.map(item => {
                    const gapStock = item.gap_stock || {};
                    return {
                        ts_code: gapStock.ts_code || '-',
                        stock_name: gapStock.stock_name || '-',
                        announce_date: gapStock.ann_date || '-',
                        gap_date: gapStock.gap_date || '-',
                        gap_pct_change: gapStock.gap_change !== null && gapStock.gap_change !== undefined ? gapStock.gap_change : '-',
                        // p_change格式为"157.0-179.0"，需要拆分为最小值和最大值
                        forecast_change_min: gapStock.p_change ? gapStock.p_change.split('-')[0] : '-',
                        forecast_change_max: gapStock.p_change ? gapStock.p_change.split('-')[1] : '-',
                        summary: gapStock.summary || '-',
                        reason: gapStock.change_reason || '-'
                    };
                });

                if (!Array.isArray(data)) {
                    throw new Error('返回数据格式错误');
                }
                
                renderProfitGapList(data);
            } catch (error) {
                console.error('刷新数据失败：', error);
                // 显示错误信息
                const profitGapTableBody = document.getElementById('profitGapTableBody');
                if (profitGapTableBody) {
                    profitGapTableBody.innerHTML = `
                        <tr>
                            <td colspan="9" class="text-center text-danger">
                                <i class="bi bi-exclamation-triangle"></i> 
                                加载数据失败：${error.message}
                            </td>
                        </tr>
                    `;
                }
            }
        }

        // 显示股票详情（占位函数，可根据需要实现）
        function showStockDetail(stockCode) {
            alert(`查看股票 ${stockCode} 的详情`);
            // 这里可以实现弹窗显示股票详情或其他交互
        }

    </script>
</body>
</html>